﻿using Obligatorio2013.Persistencia.Daos;
using Obligatorio2013.Clases;
using Obligatorio2013.Logging;
using System.Xml;
using System;
using System.Collections.Generic;
using System.Xml.Linq;

namespace Obligatorio2013.Persistencia
{
    public class UsuarioDAO : PersistentDAO
    {

        private string usersFileName = "usuarios.xml";

        public override bool Save(object obj)
        {
            try
            {
                if (!FileExist(usersFileName))
                {
                    createFileXml(path, usersFileName, "Users");
                }

                if (obj != null)
                {
                    // Crear un nuevo elemento 
                    Users usr = obj as Users;

                    XmlDocument doc = LoadXmlFile(path, usersFileName);
                    XmlElement newElement = doc.CreateElement("User");

                    // Colocar como id un valor, por ejemplo el id del Plato - podría ser cualquier otro; esto es opcional
                    addAttribute(doc, newElement, "email", usr.UserEmail);
                    // Crear los nodos hijos.
                    addElement(doc, newElement, "name", usr.UserName);
                    addElement(doc, newElement, "lastName", usr.UserLastName);
                    addElement(doc, newElement, "address", usr.UserAddress);
                    addElement(doc, newElement, "addressLocation", usr.UserAddressLocaltion);
                    addElement(doc, newElement, "phone", usr.UserPhone);
                    addElement(doc, newElement, "userId", usr.User);
                    addElement(doc, newElement, "pass", usr.UserPass);
                    addElement(doc, newElement, "role", usr.UserRole);
                    addElement(doc, newElement, "active", Convert.ToString(usr.UserActive));
                    if (!usr.UserActive)
                    {
                        addElement(doc, newElement, "inactiveUntil", Convert.ToString(usr.UserInactiveUntil));
                    }


                    // agregar el elemento al final de la lista de elementos.
                    doc.DocumentElement.AppendChild(newElement);
                    doc.Save(path + this.usersFileName);
                    return true;
                }

            }
            catch (Exception ex)
            {
                Logging.Log.Instance.Error("Error obteniendo la lista de usuarios" + ex.Message, ex);
                throw ex;
            }
            return false;
        }

        public override List<Object> getAll()
        {
            XmlReader reader = XmlReader.Create(path + "\\" + usersFileName);
            List<Object> users = null;

            XElement element = XElement.Load(reader, LoadOptions.SetBaseUri);

            IEnumerable<XElement> items = element.DescendantsAndSelf("User");

            try
            {
                if (reader != null)
                {
                    users = new List<Object>();

                    foreach (var xElement in items)
                    {
                        Users usr = new Users();
                        usr.UserEmail = GetAttributeValue("email", xElement);
                        usr.UserName = GetElementValue("name", "string", xElement);
                        usr.UserLastName = GetElementValue("lastName", "string", xElement);
                        usr.UserAddress = GetElementValue("address", "string", xElement);
                        usr.UserAddressLocaltion = GetElementValue("addressLocation", "string", xElement);
                        usr.UserPhone = GetElementValue("phone", "string", xElement);
                        usr.User = GetElementValue("userId", "string", xElement);
                        usr.UserPass = GetElementValue("pass", "string", xElement);
                        usr.UserRole = GetElementValue("role", "string", xElement);

                        usr.UserActive = Boolean.Parse(GetElementValue("active", "boolean", xElement));
                        if (!usr.UserActive)
                        {
                            usr.UserInactiveUntil = Convert.ToDateTime(GetElementValue("inactiveUntil", "date", xElement));
                        }


                        if (!String.IsNullOrEmpty(usr.UserEmail))
                        {
                            users.Add(usr);
                        }

                    }
                }
            }
            catch (Exception ex)
            {
                Log.Instance.Error("Error cargando lista : " + ex.StackTrace); 
                throw ex;
            }
            return users;
        }

        public override bool Update(Object obj)
        {

            if (FileExist(usersFileName))
            {
                Users user = obj as Users;
                XmlDocument doc = LoadXmlFile(path, usersFileName);
                XmlNode userNode = getElementByID(doc, "User", "email", user.UserEmail);

                if (userNode != null)
                {
                    try
                    {

                        userNode.Attributes["email"].Value = user.UserEmail;
                        userNode["name"].InnerText = user.UserName;
                        userNode["lastName"].InnerText = user.UserLastName;
                        userNode["address"].InnerText = user.UserAddress;
                        userNode["addressLocation"].InnerText = user.UserAddressLocaltion;
                        userNode["phone"].InnerText = user.UserPhone;
                        userNode["userId"].InnerText = user.User;
                        userNode["pass"].InnerText = user.UserPass;
                        userNode["role"].InnerText = user.UserRole;
                        userNode["active"].InnerText = Convert.ToString(user.UserActive);
                        if (!user.UserActive)
                        {
                            if (user.UserInactiveUntil != null)
                            {
                                userNode["inactiveUntil"].InnerText = user.UserInactiveUntil.ToShortDateString();
                            }
                            else
                            {
                                userNode["inactiveUntil"].InnerText = Convert.ToString(DateTime.MaxValue);
                            }
                        }
                        doc.Save(path + usersFileName);
                        return true;
                    }
                    catch (Exception ex)
                    {
                        Logging.Log.Instance.Error("Error salvando usuario." + ex.Message, ex);
                        throw new Exception();
                    }
                }
            }
            return false;
        }

        public override bool Delete(Object obj)
        {
            try
            {
                if (FileExist(usersFileName))
                {
                    Users user = obj as Users;
                    XmlDocument doc = LoadXmlFile(path, usersFileName);
                    XmlNode userNode = getElementByID(doc, "User", "email", user.UserEmail);

                    if (userNode != null)
                    {
                        doc.RemoveChild(userNode);
                        return true;
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Instance.Error("No fue posible eliminar el nodo. " + ex.Message, ex);
                throw ex;
            }
            return false;
        }
    }
}